package com.kitty.game.rank.service.handler;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.config.Equip;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.rank.message.RespRankTopUser;
import com.kitty.game.rank.model.PersonInfo;
import com.kitty.game.rank.model.Range;
import com.kitty.game.rank.model.RankType;
import com.kitty.game.rank.model.pojo.DataUnit;
import com.kitty.game.rank.model.pojo.RankGroupListData;
import com.kitty.game.rank.model.record.EquipRankRecord;
import com.kitty.game.rank.model.record.RankRecord;
import com.kitty.game.role.model.Role;
import com.kitty.game.utils.Const;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Dao;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
//后写
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**角色装备排行榜处理类*/
@Component
@Slf4j
public class EquipRankHandler extends GroupRangeRankHandler {
    /**装备类型组*/
    private List<Byte> equipGroups = new ArrayList<>();
    private Map<Short, Byte> type2Groups = new HashMap<>();

    /**等级段*/
    private List<Range<Short>> levelRanges = new ArrayList<>();

    /**初始化装备类型组*/
    @PostConstruct
    private void initGroups() {
        equipGroups.add(Const.WEAPON);
        equipGroups.add(Const.HELMET);
        equipGroups.add(Const.ARMOR);
        equipGroups.add(Const.BOOT);
    }

    /**初始化请求类型与装备类型映射关系*/
    @PostConstruct
    private void initType2Groups() {
        type2Groups.put((short) 201, Const.WEAPON);
        type2Groups.put((short) 202, Const.HELMET);
        type2Groups.put((short) 203, Const.ARMOR);
        type2Groups.put((short) 204, Const.BOOT);
    }

    /**初始化等级段*/
    @PostConstruct
    private void initRange() {
        levelRanges.add(new Range((short)70, (short)79));
        levelRanges.add(new Range((short) 80, (short) 89));
        levelRanges.add(new Range((short) 90, (short) 99));
        levelRanges.add(new Range((short) 100, (short) 109));
        levelRanges.add(new Range((short) 110, (short) 119));
        levelRanges.add(new Range((short) 120, (short) 129));
        levelRanges.add(new Range((short) 130, (short) 139));

    }

    @Override
    public void init() {
        Dao dao = SpringUtils.getBean(Dao.class);
        RankGroupListData<EquipRankRecord> equipRankData = dao.fetch(RankGroupListData.class, RankType.EQUIP.name());
        if (equipRankData != null) {
            equipRankData.doAfterInit(EquipRankRecord.class);
            List<DataUnit> rankData = equipRankData.getRankData();
            for (DataUnit dataUnit : rankData) {
                List<String> list = parseSaveKey(dataUnit.getKey());
                byte equipType = Byte.parseByte(list.get(0).trim());
                String levelRange = list.get(1).trim();
                for (RankRecord record : dataUnit.getRecords()) {
                    EquipRankRecord equipRankRecord = (EquipRankRecord) record;
                    /**改4等级以下时，不入榜*/
                    if (equipRankRecord.getUpgradeLevlel() < 4) {continue;}
                    update(equipType, levelRange, equipRankRecord.getGid(), equipRankRecord);
                }
            }
        }
    }

    public void save() {
        List<DataUnit> rankData = new ArrayList<>();
        for (byte equipType : equipGroups) {
            for (Range<Short> range : levelRanges) {
                String levelRange = getLevelRange(range);
                List<RankRecord> records = getRecordsFrom(equipType, levelRange, 0, getRankSize());
                if (records == null || records.size() == 0) {continue ;}

                String saveKey = getSaveKey(equipType, levelRange);
                DataUnit dataUnit = new DataUnit(saveKey, records);
                rankData.add(dataUnit);
            }
        }

        if (rankData.size() <= 0) {return ;}

        RankGroupListData<EquipRankRecord> equipRankData = new RankGroupListData<>(RankType.EQUIP, rankData);
        equipRankData.doBeforeSave();
        Dao dao = SpringUtils.getBean(Dao.class);
        dao.insertOrUpdate(equipRankData);
    }

    @PreDestroy
    private void shutDown() {
        save();
        log.error("[{}]保存数据后关闭", this.getClass().getSimpleName());
    }

    private String getLevelRange(Range range) {
        return range.getMin() + "-" + range.getMax();
    }

    private Range getRange(short roleLevel) {
        for (Range<Short> range : levelRanges) {
            if (roleLevel >= range.getMin() && roleLevel <= range.getMax()) {
                return range;
            }
        }

        return null;
    }

    private String getSaveKey(byte equipType, String levelRange) {
        return equipType + "_" + levelRange;
    }

    private List<String> parseSaveKey(String key) {
        String[] arrays = key.split("_", 2);
        return Arrays.asList(arrays);
    }

    public RespRankTopUser getRankResponse(short type, String range) {
        RespRankTopUser respRankTopUser = new RespRankTopUser();
        respRankTopUser.setType(type);
        respRankTopUser.setCookie(new Long(System.currentTimeMillis() / 1000).intValue());
        respRankTopUser.setList(new ArrayList<>());
        List<PersonInfo> personInfoList = getPersonInfoList(getRecordsFrom(type, range));
        respRankTopUser.setList(personInfoList);
        respRankTopUser.setSize((short) respRankTopUser.getList().size());
        String[] levels = range.split("-");
        respRankTopUser.setMin(Short.parseShort(levels[0]));
        respRankTopUser.setMax(Short.parseShort(levels[1]));
        return respRankTopUser;
    }

    public List<RankRecord> getRecordsFrom(short type, String range) {
        byte equipType = type2Groups.get(type);
        return getRecordsFrom(equipType, range, 0, getRankSize());
    }

    private List<PersonInfo> getPersonInfoList(List<RankRecord> records) {
        List<PersonInfo> list = new ArrayList<>(records.size());
        for (RankRecord rankRecord : records) {
            EquipRankRecord equipRankRecord = (EquipRankRecord)rankRecord;
            PersonInfo personInfo = new PersonInfo();
            personInfo.setList(new ArrayList<>());
            personInfo.getList().add(new FiedValue(306, equipRankRecord.getGid()));
            personInfo.getList().add(new FiedValue(1, equipRankRecord.getName()));
            personInfo.getList().add(new FiedValue(208, equipRankRecord.getUpgradeLevlel()));
            personInfo.getList().add(new FiedValue(176, equipRankRecord.getRoleName()));
            personInfo.getList().add(new FiedValue(889, equipRankRecord.getPerfect()));
            personInfo.getList().add(new FiedValue(31, equipRankRecord.getLevel()));
            list.add(personInfo);
        }
        return list;
    }

    public void updateUpgradeLevelChange(Role role, RoleEquip roleEquip, short prevUpgradeLevel, short upgradeLevel) {
        Equip equip = EquipDataPool.getByName(roleEquip.getName());
        /**改4等级以下时，不入榜*/
        /** 需要判断之前的改造等级，因为改造等级可能降低，需要移出*/
        if (upgradeLevel < 4 && prevUpgradeLevel >= 4) {
            removeRank(roleEquip, equip);
            return ;
        }
        update(roleEquip, String.valueOf(roleEquip.getId()), equip.getPosition(), equip.getReq_level(), equip.getKey_name(), upgradeLevel, role.getName(), roleEquip.getPerfect());
    }

    private void removeRank(RoleEquip roleEquip, Equip equip) {
        Range range = getRange(equip.getReq_level());
        /**等级没有在等级段内*/
        if (range == null) {return ;}

        String levelRange = getLevelRange(range);
        remove(equip.getPosition(), levelRange, String.valueOf(roleEquip.getId()));
    }

    public void updatePerfectChange(Role role, RoleEquip roleEquip, int perfect) {
        Equip equip = EquipDataPool.getByName(roleEquip.getName());
        update(roleEquip, String.valueOf(roleEquip.getId()), equip.getPosition(), equip.getReq_level(), equip.getKey_name(), roleEquip.queryUpgradeLevel(), role.getName(), perfect);
    }

    private void update(RoleEquip roleEquip, String gid, byte equipType, short level, String name, short upgradeLevel, String roleName, int perfect) {
        Range range = getRange(level);
        /**等级没有在等级段内*/
        if (range == null) {return ;}
        /**改4等级以下时，不入榜*/
        if (upgradeLevel < 4) {return ;}

        String levelRange = getLevelRange(range);
        boolean update = update(equipType, levelRange, gid, new EquipRankRecord(gid, name, upgradeLevel, roleName, perfect, level));
        if (update) {
            List<EquipField> equipFields = SpringUtils.getEquipService().transferList(roleEquip.getFields());
            SpringUtils.getRankService().addRankView(gid, equipFields);
        }
    }

    /**
     * 删除装备更新排行榜
     */
    public void updateAfterRemove(RoleEquip roleEquip) {
        Equip equip = EquipDataPool.getByName(roleEquip.getName());
        /**不是装备不处理*/
        if (equip == null) {return ;}

        Range range = getRange(equip.getReq_level());
        /**等级没有在等级段内*/
        if (range == null) {return ;}
        /**改4等级以下时，不入榜*/
        short upgradeLevel = roleEquip.queryUpgradeLevel();
        if (upgradeLevel < 4) {return ;}

        byte equipType = equip.getPosition();
        String levelRange = getLevelRange(range);
        String gid = String.valueOf(roleEquip.getId());
        remove(equipType, levelRange, gid);
    }
}
